#include "menu.h"
#include "LeaderBoard.h"
#include "game.h"
#include <string>
#include <iostream>
#include "DEBUG.h"

using namespace std;

ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer = NULL;
ALLEGRO_FONT *font50 = NULL;
ALLEGRO_FONT *font18 = NULL;
ALLEGRO_EVENT ev;
  
bool done; 
///@param WIDTH_DISPLAY stores the width of the display
const unsigned short int WIDTH_DISPLAY = 500;
///@param HEIGHT_DISPLAY stores the height of the display
const unsigned short int HEIGHT_DISPLAY= 700;
 
 

//Here we create an two variables for the state change in the state machine
/**
 * The enumerator @enum state indicates in which state the game is. We can
 * have only three states:
 * @param m_menu in which the game is when you start the software; here the player
 *         can start a new game or quit the game.
 * @param p_chart where the player cans check our best record.
 * @param in_game where the player plays the game
 * 
 * Here we also create two variables:
 * @param act_state where is store the transition of the state
 * @param prec_state where is stored the precedent state of the menu
 */
enum state {m_menu, p_chart, in_game} act_state, prec_state;

void InitMenu(bttnbox bttn[]);
void DrawMenu (bttnbox bttn[]);
bool CheckBttnPush (bool redraw, state &act_state, bttnbox menu_bttn[]);


bool InitAllegro (){
  if(!al_init())										//initialize allegro
		return false;
  
  al_init_font_addon();
  al_init_ttf_addon();
  al_install_mouse();
  al_install_keyboard();
  
  display = al_create_display(WIDTH_DISPLAY, HEIGHT_DISPLAY);			

  if(!display)										//test display object
    return false;
  
  font50 = al_load_font("./../res/unitedplanets3d.ttf", 50, 0);
  assert(font50);
  
  font18 = al_load_font("./../res/NEWACADEMY.ttf", 18, 0); 
  assert(font18);   
  
  event_queue = al_create_event_queue(); // a container for the event we register during the game.
  assert(event_queue);
  
  const unsigned short int FPS = 60;
  timer = al_create_timer(1.0 / FPS);
  assert(timer);
  
  al_register_event_source(event_queue, al_get_mouse_event_source());
  al_register_event_source(event_queue, al_get_keyboard_event_source());
  al_register_event_source(event_queue, al_get_display_event_source(display));
  al_register_event_source(event_queue, al_get_timer_event_source(timer));
  
  return true;
}

int Menu (){
  const unsigned short int number_of_button = 4;
  bttnbox menu_bttn [number_of_button];
 
  done = false;
  bool redraw = true;
  act_state = m_menu;
  prec_state = p_chart;
  
  InitMenu(menu_bttn);
  LoadLeaderBoard();
  BoardHeapSort();
  al_start_timer(timer);
  
  while (!done){
    al_wait_for_event(event_queue, &ev);
    
    if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE){ //close game
      switch (act_state){
        case m_menu:
          done = true;
          break;
        case p_chart:
        case in_game:
          act_state = m_menu;
          break;
        default:
          break;
      }
    }
    else if (ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP){
        done = CheckBttnPush(redraw, act_state, menu_bttn);
    }
         
    if (act_state != prec_state && act_state == m_menu){
      DrawMenu(menu_bttn);
      prec_state = act_state;
      redraw = true;
    } else if (act_state != prec_state && act_state == p_chart){
      ShowLeaderBoard(WIDTH_DISPLAY, HEIGHT_DISPLAY, menu_bttn);
      prec_state = act_state;
      redraw = true;
    } else if (act_state != prec_state && act_state == in_game){
      al_flush_event_queue(event_queue);
      prec_state = act_state;
      return Game();
    } 

    if(redraw && al_is_event_queue_empty(event_queue)){
      al_flip_display();
      al_clear_to_color(al_map_rgb(0,0,0));
      al_set_timer_count(timer, 1.0/60);
      redraw = false;
    }
  }
  return 0;
}

void InitMenu(bttnbox bttn[]){
  //create and initialize 3 buttons
  char new_game[]="New Game";
  char leaders_board [] ="LeaderBoard";
  char quit []= "Quit";
  char backto [] = "Main Menu";
  
  InitBttn(bttn[newgame], WIDTH_DISPLAY/2 - bttn[newgame].bttn_width /2, HEIGHT_DISPLAY/2,new_game);
  InitBttn(bttn[leaderBoard], WIDTH_DISPLAY/2 - bttn[leaderBoard].bttn_width/2, HEIGHT_DISPLAY/2 +80, leaders_board);
  InitBttn(bttn[quitting], WIDTH_DISPLAY/2 - bttn[quitting].bttn_width/2, HEIGHT_DISPLAY/2 + 160, quit);
  InitBttn(bttn[back], WIDTH_DISPLAY/2-bttn[back].bttn_width/2, HEIGHT_DISPLAY-(HEIGHT_DISPLAY/4), backto );
}

void DrawMenu (bttnbox bttn[]){
  //draw the title
  char gameName [] = "TETRIS";
  int textLenght = al_get_text_width(font50, gameName);
  al_draw_text(font50, al_map_rgb(255,255,255), WIDTH_DISPLAY/2- textLenght/2, (HEIGHT_DISPLAY/4),0, gameName);
  
  //render function
  DrawBttn(bttn[newgame]);
  DrawBttn(bttn[leaderBoard]);
  DrawBttn(bttn[quitting]);
}

void Close (){
  al_destroy_display(display);
  al_destroy_event_queue(event_queue);
  al_destroy_font(font18);
  al_destroy_font(font50);
  al_destroy_timer(timer);
  
  al_uninstall_keyboard();
  al_uninstall_mouse();
}

bool CheckBttnPush (bool redraw, state &act_state, bttnbox menu_bttn[]){ 
  ALLEGRO_MOUSE_STATE mouse_pos;
  al_get_mouse_state(&mouse_pos);
  
  D1(cout<<"Mouse X position:"<<mouse_pos.x<<endl
    <<"Mouse Y position:"<<mouse_pos.y<<endl;);
  
  //this check if the mouse pointer_x could be on a button in the main_menu state
  if ((act_state == m_menu) && (mouse_pos.x>=menu_bttn[newgame].center_x) && 
      (mouse_pos.x<=(menu_bttn[newgame].center_x+ menu_bttn[newgame].bttn_width))){
    //this check if the mouse pointer_y is on the new game button
    if ((mouse_pos.y>=menu_bttn[newgame].center_y) && 
        (mouse_pos.y<=(menu_bttn[newgame].center_y+menu_bttn[newgame].bttn_height))){
      act_state = in_game;
    D1(cout<<"Actual State:"<<act_state<<endl);
    }
    //this check if the mouse pointer_y is on the leaderboard button
    else if ((mouse_pos.y>=menu_bttn[leaderBoard].center_y) && 
             (mouse_pos.y<=(menu_bttn[leaderBoard].center_y+menu_bttn[leaderBoard].bttn_height))){
      act_state = p_chart;
      D1(cout<<"Actual State:"<<act_state<<endl);
    }
    //this check if the mouse pointer_y is on the quit button
    else if ((mouse_pos.y>=menu_bttn[quitting].center_y) && 
             (mouse_pos.y<=(menu_bttn[quitting].center_y+menu_bttn[quitting].bttn_height)))
      return true;
  }
  //this check if the mouse pointer_x could be on a button in the p_chart state
  else if ((act_state == p_chart) && 
           (mouse_pos.x>=menu_bttn[newgame].center_x) && 
           (mouse_pos.x<=(menu_bttn[newgame].center_x+ menu_bttn[newgame].bttn_width))){
    //this check if the mouse pointer_y could be the button Main Menu
    if ((mouse_pos.y>=menu_bttn[back].center_y) && 
        ((mouse_pos.y<=(menu_bttn[back].center_y+menu_bttn[back].bttn_height)) == p_chart)){
      act_state = m_menu;
      D1(cout<<"Actual State:"<<act_state<<endl);
    }
  }
  return false;
}

void DrawBttn (bttnbox thisb){
    al_draw_rectangle(thisb.center_x, thisb.center_y, thisb.center_x+thisb.bttn_width, thisb.center_y+thisb.bttn_height, al_map_rgb(255,0,250), 3.0);
        
    assert(font18);
    int text_lenght = al_get_text_width(font18, thisb.text);
    al_draw_text(font18, al_map_rgb(200,200,200), thisb.center_x+(thisb.bttn_width-text_lenght)/2, thisb.center_y+15, 0, thisb.p_text);
}

void InitBttn(bttnbox &thisb, float cntr_x, float cntr_y, char thistext[]){
    thisb.center_x = cntr_x;
    thisb.center_y = cntr_y;
               
    strcpy(thisb.text, thistext);
}
